<?php
/**
 * Created by PhpStorm
 * User: Jhinwy
 * Date: 5/27/24
 * Time: 11:42 AM
 */

namespace App\Services;


use App\Models\WechatActiveCode;
use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

class OrderService
{
    const REDIS_CORP_WECHAT_PROVIDER_ACCESS_TOKEN = 'corp_wechat_provider_access_toen_';

    public $api = [];

    public $headers = ['Content-Type' => 'application/json'];

    protected $providerSecret;

    public function __construct()
    {
        $this->api = config('corp_wechat');

        $this->providerSecret = env('CORP_WECHAT_PROVIDER_SECRET');
    }


    /**
     * 获取服务商token
     *
     * @return mixed|string
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function getAccessToken($corpId)
    {
        if ($accessToken = Cache::get(self::REDIS_CORP_WECHAT_PROVIDER_ACCESS_TOKEN . $corpId)) {

            return $accessToken;
        }
        try {

            $client   = new Client();
            $body     = [
                'headers'            => $this->headers,
                RequestOptions::JSON => [
                    'corpid'          => $corpId,
                    'provider_secret' => $this->providerSecret
                ]
            ];
            $response = $client->request('POST', $this->api['provider_access_token'], $body);
            if ($response->getStatusCode() != 200) {
                throw new \Exception('请求失败！');
            }
            $contents    = $response->getBody()->getContents();
            $data        = json_decode($contents, true);
            $accessToken = $data['provider_access_token'] ?? '';
            $expiresIn   = $data['expires_in'] ?? 0;
            if (!$accessToken || !$expiresIn) {
                throw new \Exception('代开发应用服务商token不存在');
            }
            Cache::put(self::REDIS_CORP_WECHAT_PROVIDER_ACCESS_TOKEN . $corpId, $accessToken, $expiresIn);

            return $accessToken;
        } catch (\Exception $exception) {
            Log::error('获取代开发应用服务商token失败：' . $exception->getMessage());

            return false;
        }
    }


    /**
     * 获取订单列表
     *
     * @param $params
     * @return array|bool
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function getOrderList($params)
    {
        $corpId     = $params['corp_id'] ?? '';
        $nextCursor = $params['next_cursor'] ?? '';

        try {
            $bodyData = ['corpid' => $corpId];
            if ($nextCursor) {
                $bodyData['cursor'] = $nextCursor;
            }

            $client   = new Client();
            $body     = [
                'headers'            => $this->headers,
                RequestOptions::JSON => $bodyData
            ];
            $response = $client->request(
                'POST',
                sprintf($this->api['order_list'], $this->getAccessToken($corpId)),
                $body
            );
            if ($response->getStatusCode() != 200) {
                throw new \Exception('请求失败！');
            }
            $contents = $response->getBody()->getContents();
            $data     = json_decode($contents, true);
            if ($data['errcode'] != 0) {

                return [];
            }
            return [
                'has_more'    => $data['has_more'] ?? 0,
                'next_cursor' => $data['next_cursor'] ?? '',
                'order_list'  => $data['order_list'] ?? []
            ];
        } catch (\Exception $exception) {
            Log::error('获订单列表失败：' . $exception->getMessage());

            return false;
        }
    }


    /**
     * 激活码列表
     *
     * @param $params
     * @return array|bool
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function getCodeList($params)
    {
        $corpId     = $params['corp_id'] ?? '';
        $orderId    = $params['order_id'] ?? '';
        $nextCursor = $params['next_cursor'] ?? '';

        try {
            $client   = new Client();
            $bodyData = ['order_id' => $orderId];
            if ($nextCursor) {
                $bodyData['cursor'] = $nextCursor;
            }
            $body     = [
                'headers'            => $this->headers,
                RequestOptions::JSON => $bodyData
            ];
            $response = $client->request(
                'POST',
                sprintf($this->api['code_list'], $this->getAccessToken($corpId)),
                $body
            );
            if ($response->getStatusCode() != 200) {
                throw new \Exception('请求失败！');
            }
            $contents = $response->getBody()->getContents();
            $data     = json_decode($contents, true);
            if ($data['errcode'] != 0) {

                return [];
            }
            if (!$codeList = $data['account_list'] ?? []) {

                return [];
            }
            foreach ($codeList as &$item) {
                $code           = WechatActiveCode::query()->where('active_code', $item['active_code'])->first();
                $item['is_use'] = $code ? 1 : 0;
            }

            return [
                'has_more'    => $data['has_more'] ?? 0,
                'next_cursor' => $data['next_cursor'] ?? '',
                'code_list'   => $codeList
            ];
        } catch (\Exception $exception) {
            Log::error('获激活码列表失败：' . $exception->getMessage());

            return false;
        }
    }


    /**
     * 激活账号
     *
     * @param $params
     * @return bool
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function activeAccount($params)
    {
        $corpId     = $params['corp_id'] ?? '';
        $activeCode = $params['active_code'] ?? '';
        $userId     = $params['userid'] ?? '';

        $code = WechatActiveCode::query()->where('active_code', $activeCode)->first();
        if ($code) {

            return '激活码已被使用';
        }

        try {
            $client   = new Client();
            $body     = [
                'headers'            => $this->headers,
                RequestOptions::JSON => [
                    'active_code' => $activeCode,
                    'corpid'      => $corpId,
                    'userid'      => $userId
                ]
            ];
            $response = $client->request(
                'POST',
                sprintf($this->api['active_account'], $this->getAccessToken($corpId)),
                $body
            );
            if ($response->getStatusCode() != 200) {
                throw new \Exception('请求失败！');
            }
            $contents = $response->getBody()->getContents();
            Log::info('激活账号：', [$contents, $body]);
            $data = json_decode($contents, true);
            if ($data['errcode'] != 0) {

                throw new \Exception($data['errmsg'] ?? '激活失败');
            }
            $codeModel              = new WechatActiveCode();
            $codeModel->corp_id     = $corpId;
            $codeModel->user_id     = $userId;
            $codeModel->active_code = $activeCode;
            $codeModel->save();

            return true;
        } catch (\Exception $exception) {
            Log::error('激活账号失败：' . $exception->getMessage());

            return $exception->getMessage();
        }
    }
}
